package com.spice.im.chat;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import com.dodola.model.UnReadMsgNumber;
import com.lidroid.xutils.DbUtils;
import com.lidroid.xutils.db.sqlite.Selector;
import com.lidroid.xutils.db.sqlite.WhereBuilder;
import com.lidroid.xutils.exception.DbException;

import android.content.Context;
import android.os.Environment;
//import android.os.RemoteException;
import android.util.Log;

import com.spice.im.utils.StringUtils;
import com.stb.core.chat.Message;
public class ChatAdapterOffline {
	private static final int HISTORY_MAX_SIZE = 50;
	private List<Message> mMessages;
	private boolean mIsHistory = true;
	private File mHistoryPath;
	private String historyPath;
	
	private Context mContext;
	public ChatAdapterOffline(Context context){
		this.mContext = context;
		mMessages = new LinkedList<Message>();
		initialDB();
		historyPath = "/Android/data/com.stb.isharemessage/chat/";
		mHistoryPath = new File(Environment.getExternalStorageDirectory(), historyPath);
	}
	public void setContext(Context context){
		mContext = context;
	}
	public Context getContext(){
		return mContext;
	}
	private DbUtils db;
	public void initialDB(){
		db = DbUtils.create(mContext);
	    db.configAllowTransaction(true);
	    db.configDebug(true);
	}
	
	
	public List<Message> getMessages() {
		Collections.sort(mMessages);
		return mMessages;
	}
	
	private List<Message> list = null;
	public List<Message> getMessagesByPageIndex(String AccountUser,String Participant,int pageSize,int pageNum) {
		try{
			int pageIndex = pageNum;
			if(Participant.indexOf("@1")==-1)//@conference.
				list = db.findAll(Selector.from(Message.class)  
				   .where(WhereBuilder.b("mfrom","=",StringUtils.parseBareAddress(AccountUser)).and("mto","=",StringUtils.parseBareAddress(Participant)))
				   .or(WhereBuilder.b("mto","=",StringUtils.parseBareAddress(AccountUser)).and("mfrom","=",StringUtils.parseBareAddress(Participant)))
				   .orderBy("mtimestamp",true)//倒序排列true 顺序排列false
	              .limit(pageSize)  //pageSize
	              .offset(pageSize * pageIndex)); //pageSize * pageIndex
			else if(Participant.indexOf("@1")!=-1)//考虑客户端接收消息及发送消息两种情形
				list = db.findAll(Selector.from(Message.class)  
									   .where(WhereBuilder.b("mfrom","=",StringUtils.parseBareAddress(Participant)+"//"+StringUtils.parseName(AccountUser)).and("mto","=",StringUtils.parseBareAddress(AccountUser)))
									   .or(WhereBuilder.b("mto","=",StringUtils.parseBareAddress(AccountUser)).and("mfrom","LIKE",StringUtils.parseBareAddress(Participant)+"%"))
									   .or(WhereBuilder.b("mfrom","=",StringUtils.parseBareAddress(Participant)+"//"+StringUtils.parseName(AccountUser)).and("mto","=",StringUtils.parseBareAddress(Participant)))
									   .or(WhereBuilder.b("mto","=",StringUtils.parseBareAddress(Participant)).and("mfrom","LIKE",StringUtils.parseBareAddress(Participant)+"%"))
									   .orderBy("mtimestamp",true)//倒序排列true 顺序排列false
						              .limit(pageSize)  //pageSize
						              .offset(pageSize * pageIndex)); //pageSize * pageIndex    	
	        if(list!=null){
	        	Collections.sort(list);
	        	for(int i=0;i<list.size();i++){
	        		Log.e("++++++++20140620getMessagesByPageIndex++++++++","++++++++getMessagesByPageIndex++++++++Message("+i+")"+(Message)list.get(i));
	        	}
	        	
	        	mMessages = list;
	        }
	        return list;
		}catch(DbException e){
			e.printStackTrace();
		}
	    return null;
	}
	public long getAllMessagesCount(String AccountUser,String Participant){
		try{
			
			if(Participant.indexOf("@1")==-1)
				return db.count(Selector.from(Message.class).where(WhereBuilder.b("mfrom","=",StringUtils.parseBareAddress(AccountUser)).and("mto","=",StringUtils.parseBareAddress(Participant)))
						.or(WhereBuilder.b("mto","=",StringUtils.parseBareAddress(AccountUser)).and("mfrom","=",StringUtils.parseBareAddress(Participant))));
			else if(Participant.indexOf("@1")!=-1)
				return db.count(Selector.from(Message.class).where(WhereBuilder.b("mfrom","=",StringUtils.parseBareAddress(Participant)+"//"+StringUtils.parseName(AccountUser)).and("mto","=",StringUtils.parseBareAddress(AccountUser)))
						   .or(WhereBuilder.b("mto","=",StringUtils.parseBareAddress(AccountUser)).and("mfrom","LIKE",StringUtils.parseBareAddress(Participant)+"%"))
						   .or(WhereBuilder.b("mfrom","=",StringUtils.parseBareAddress(Participant)+"//"+StringUtils.parseName(AccountUser)).and("mto","=",StringUtils.parseBareAddress(Participant)))
						   .or(WhereBuilder.b("mto","=",StringUtils.parseBareAddress(Participant)).and("mfrom","LIKE",StringUtils.parseBareAddress(Participant)+"%"))
				);
		}catch(DbException e){
			e.printStackTrace();
		}catch(Exception e){
			e.printStackTrace();
		}
		return 0;
	}
	
	public int addMessage(String AccountUser,String Participant,Message msg) {
		Log.e("++++++++20140605addMessage1++++++++","++++++++addMessage1++++++++"+msg.toString());
		try{
			UnReadMsgNumber unReadMsgNumber = null;
	    		unReadMsgNumber = db.findById(UnReadMsgNumber.class, StringUtils.parseBareAddress(msg.getMfrom()));//parseName
	    	if(unReadMsgNumber !=null )
	    		unReadMsgNumber.setUnreadnumber(unReadMsgNumber.getUnreadnumber()+1);
	    	else{
	    		unReadMsgNumber = new UnReadMsgNumber();
		    	unReadMsgNumber.setKey(StringUtils.parseBareAddress(msg.getMfrom()));

	    		unReadMsgNumber.setUnreadnumber(1);
	    	}
	    	db.saveOrUpdate(unReadMsgNumber);
		}catch (DbException e) {
	        e.printStackTrace();
	        
	    } catch (Exception e){
	    	e.printStackTrace();
	    }
		if (mMessages.size() == HISTORY_MAX_SIZE)
		    mMessages.remove(0);
		mMessages.add(msg);
		if (!"".equals(msg.getMbody()) && msg.getMbody() != null) {
		    return logMessage(AccountUser,Participant,msg);
		}
		return 0;
	}
	
	public void updateMessage(String AccountUser,String Participant,int position,int UpDownType,int isOffline,int id) {
		Log.e("※※※※※####20140806####※※※※※", "※※数据库记录更新※※position="+position+";UpDownType="+UpDownType+";isOffline="+isOffline);
		if(position<mMessages.size()){
	    	mMessages.get(position).setMupdowntype(UpDownType);
	    	mMessages.get(position).setMisoffline(isOffline);
	    	try{
		        Message message = new Message();
		        message.setMtype(mMessages.get(position).getMtype());
		        if(mMessages.get(position).getMfrom()!=null 
		        		&& !mMessages.get(position).getMfrom().equalsIgnoreCase("null")
		        		&& mMessages.get(position).getMfrom().length()!=0
		        		&& !mMessages.get(position).getMfrom().equalsIgnoreCase("Me"))
		        	message.setMfrom(mMessages.get(position).getMfrom());
		        else
		        	message.setMfrom(sqliteEscape(AccountUser));
		        if(message.getMfrom().indexOf("@1")!=-1)
		        	message.setMfrom(message.getMfrom());
		        else
		        	message.setMfrom(StringUtils.parseBareAddress(message.getMfrom()));
		        
		        if(mMessages.get(position).getMto()!=null 
		        		&& !mMessages.get(position).getMto().equalsIgnoreCase("null")
		        		&& mMessages.get(position).getMto().length()!=0
		        		&& !mMessages.get(position).getMto().equalsIgnoreCase("Me"))
		        	message.setMto(mMessages.get(position).getMto());
		        else
		        	message.setMto(sqliteEscape(StringUtils.parseBareAddress(Participant)));
		        if(message.getMto().indexOf("@1")!=-1)
		        	message.setMto(message.getMto());
		        else
		        	message.setMto(StringUtils.parseBareAddress(message.getMto()));
		        message.setMbody(mMessages.get(position).getMbody());
		        message.setMsubject(mMessages.get(position).getMsubject());
		        message.setMtimestamp(mMessages.get(position).getMtimestamp());
		        message.setMupdowntype(mMessages.get(position).getMupdowntype());
		        message.setMisoffline(mMessages.get(position).getMisoffline());
		        message.setMthread(mMessages.get(position).getMthread());
		        
		        db.update(message, WhereBuilder.b("mto", "=", message.getMto()).and("mfrom", "=", message.getMfrom()).and("id", "=", id), new String[]{"mupdowntype","misoffline"});//,"mIsOffline"
		        
		        List<Message> children = db.findAll(Selector.from(Message.class));
		        Log.e("※※※※※####20140806####※※※※※", "※※数据库记录更新※※children size:" + children.size());
		        if (children.size() > 0) {
		        	for(int i=0;i<children.size();i++)
		        		Log.e("※※※※※####20140806####※※※※※", "※※数据库记录更新※※last children:" + children.get(i));
		        }
		        children = null;
	        } catch (DbException e) {
	            e.printStackTrace();
	            
	        } catch (Exception e){
	        	e.printStackTrace();
	        }
		}
	}
	
	private int logMessage(String AccountUser,String Participant,Message message) {
		String state = Environment.getExternalStorageState();
		if (mIsHistory && Environment.MEDIA_MOUNTED.equals(state))
		    saveHistory(message, AccountUser);
			try{
			    if(message.getMfrom()!=null 
			    		&& !message.getMfrom().equalsIgnoreCase("null")
			    		&& message.getMfrom().length()!=0
			    		&& !message.getMfrom().equalsIgnoreCase("Me"))
		//	    	messageDB.setFrom(message.getFrom());
			    	;
			    else
			    	message.setMfrom(AccountUser);
			    if(message.getMfrom().indexOf("@1")!=-1)
			    	message.setMfrom(sqliteEscape(message.getMfrom()));
			    else
			    	message.setMfrom(StringUtils.parseBareAddress(message.getMfrom()));
			    if(message.getMto()!=null 
			    		&& !message.getMto().equalsIgnoreCase("null")
			    		&& message.getMto().length()!=0
			    		&& !message.getMto().equalsIgnoreCase("Me"))
		//	    	messageDB.setTo(message.getTo());
			    	;
			    else
			    	message.setMto(StringUtils.parseBareAddress(Participant));
			    if(message.getMto().indexOf("@1")!=-1)
			    	message.setMto(sqliteEscape(message.getMto()));
			    else
			    	message.setMto(StringUtils.parseBareAddress(message.getMto()));
			    message.setMupdowntype(0);
		
			    db.saveBindingId(message);//保存对象关联数据库生成的id   保存一条记录
		//	    db.saveOrUpdate(message);

		    } catch (DbException e) {
		        e.printStackTrace();
		        
		    } catch (Exception e){
		    	e.printStackTrace();
		    }
	    Log.e("※※※※※####20140807####※※※※※", "※※数据库logMessage id※※:"+message.getId());
		return message.getId();
	    
	}
	
	public void saveHistory(Message msg, String contactName) {
		File path = getHistoryPath();
		File filepath;
		if (contactName.equals(msg.getMfrom()))
		    filepath = new File(path, StringUtils.parseBareAddress(contactName));
		else
		    filepath = new File(path, StringUtils.parseBareAddress(msg.getMto()));
		path.mkdirs();
		try {
		    FileWriter file = new FileWriter(filepath, true);
		    String log = msg.getMtimestamp() + " " + contactName + " " + msg.getMbody()
			+ System.getProperty("line.separator");
		    
		    Log.e("201211019***************>>>>>>>>>>>", log);
		    
		    file.write(log);
		    file.close();
		} catch (IOException e) {
		    e.printStackTrace();
		}
	}
	
	public void setHistoryPath(File historyPath) {
		this.mHistoryPath = historyPath;
		}

		/**
		 * get History path.
		 * @return mHistoryPath;
		 */
	public File getHistoryPath() {
		return mHistoryPath;
	}
		
	public static String sqliteEscape(String keyWord){  
	    keyWord = keyWord.replace("/", "//");  
	    keyWord = keyWord.replace("'", "''");  
	    keyWord = keyWord.replace("[", "/[");  
	    keyWord = keyWord.replace("]", "/]");  
	    keyWord = keyWord.replace("%", "/%");  
	    keyWord = keyWord.replace("&","/&");  
	    keyWord = keyWord.replace("_", "/_");  
	    keyWord = keyWord.replace("(", "/(");  
	    keyWord = keyWord.replace(")", "/)");  
	    return keyWord;  
	}
	
	
}
